/*****************************
 *@file: BlastBullet
 *@author: 陈吕唐
 *@desc: 爆炸子弹 //TODO: 待完善真正用爆炸实现
 *@date: 2024-03-18	16:23
 *****************************/
import { _decorator, Collider2D, Contact2DType, IPhysics2DContact, warn } from 'cc';
import { BaseCharacter } from '../BaseCharacter';
import GameUtils from '../GameUtils';
import { PhysicsEnum } from '../PhysicsEnum';
import { BaseBullet } from './BaseBullet';
const { ccclass, property } = _decorator;

@ccclass('BlastBullet')
export class BlastBullet extends BaseBullet {
    /****************************************************************************************************************
     *Readonly 常量
     ****************************************************************************************************************/
    /****************************************************************************************************************
     *Property 定义变量
     ****************************************************************************************************************/
    /**
     * 在爆炸范围内的战斗单位
     */
    protected sensorCharacterSet: Set<BaseCharacter> = new Set();
    /***************************************************************
     *PropertyUI 引用的控件
     ***************************************************************/
    @property({ group: { name: 'Blast', id: '2' }, type: Collider2D, tooltip: `当前爆炸范围形状` })
    protected sensorCollider: Collider2D = null;
    /****************************************************************************************************************
     * Lifecycle 生命周期相关方法
     ****************************************************************************************************************/
    protected onLoad(): void {
        super.onLoad();
        let colliders = this.node.getComponents(Collider2D);
        if (!this.sensorCollider) {
            this.sensorCollider = colliders.find((c) => c.tag === PhysicsEnum.ColliderTagGroup.SENSOR);
        }
        this.addSensorListener(this.sensorCollider)
    }
    /****************************************************************************************************************
     * Public 公有方法
     ****************************************************************************************************************/
    /****************************************************************************************************************
     * private 私有方法
     ****************************************************************************************************************/
    /**
     * 进入感应范围时调用
     * @param selfCollider 
     * @param otherCollider 
     * @param contact 
     */
    private onBeginSensorContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 只在两个碰撞体开始接触时被调用一次

        let character = GameUtils.getCharacterByCollider(otherCollider);
        if (character) {
            this.sensorCharacterSet.add(character);
        }
    }

    /**
     * 退出感应范围时调用
     * @param selfCollider 
     * @param otherCollider 
     * @param contact 
     */
    protected onEndSensorContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
        // 只在两个碰撞体结束接触时被调用一次

        let character = GameUtils.getCharacterByCollider(otherCollider);
        if (character) {
            this.sensorCharacterSet.delete(character);
        }
    }

    /**
     * 添加感应范围监听
     * @param collider 
     * @returns 
     */
    private addSensorListener(collider: Collider2D) {
        if (!collider) {
            warn('collider is null');
            return;
        }

        if (!collider.hasEventListener(Contact2DType.BEGIN_CONTACT, this.onBeginSensorContact, this)) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginSensorContact, this);
        }
        if (!collider.hasEventListener(Contact2DType.END_CONTACT, this.onEndSensorContact, this)) {
            collider.on(Contact2DType.END_CONTACT, this.onEndSensorContact, this);
        }
    }
    /****************************************************************************************************************
     * Property Get && Set 属性的 get && set 函数
     ****************************************************************************************************************/
}


